
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;

public class Connector extends Thread {

    private Socket socket;
    private String host;
    private final int PORT = 12345;
    private int id;
    private Bomberman bomberman;
    private BomberServer bomberserver;

    public Connector(Bomberman bomberman, String host) {
        this.bomberman = bomberman;
        this.host = host;
    }

    public Connector(BomberServer bomberserver, Socket socket, int id) {
        this.bomberserver = bomberserver;
        this.socket = socket;
        this.id = id;
        start();
    }

    public void run() {
        byte[] b = new byte[8];
        try {
            while (socket.getInputStream().read(b) >= 0) {
                read(b);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (bomberserver != null) {
            bomberserver.disconnect(id);
        }
    }

    public boolean connect() {
        try {
            socket = new Socket(host, PORT);
            start();
            return true;
        } catch (Exception e) {
        }
        return false;
    }

    public Object readObject() {
        try {
            return new ObjectInputStream(socket.getInputStream()).readObject();
        } catch (Exception e) {
        }
        return null;
    }

    private byte[] intToByte(int i) {
        byte[] b = new byte[2];
        b[0] = (byte) ((i >> 8) & 0xFF);
        b[1] = (byte) (i & 0xFF);
        return b;
    }

    public void send(int[] all) {
        byte[] send = new byte[8];
        send[0] = (byte) all[0];
        for (int i = 1; i < all.length; i++) {
            byte[] b = intToByte(all[i]);
            send[(i - 1) * 2 + 1] = b[0];
            send[(i - 1) * 2 + 2] = b[1];
        }
        try {
            socket.getOutputStream().write(send);
        } catch (Exception e) {
        }
    }

    public void sendObject(int cmd, Object o) {
        try {
            int[] all = {cmd};
            send(all);
            ObjectOutputStream oOut = new ObjectOutputStream(socket.getOutputStream());
            oOut.writeObject(o);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private int byteToInt(byte b1, byte b2) {
        int i = 0;
        i |= b1 & 0xFF;
        i <<= 8;
        i |= b2 & 0xFF;
        return i;
    }

    public void read(byte[] b) {
        switch (b[0]) {
            case 0:
                bomberman.size(byteToInt(b[1], b[2]));
                break;
            case 1:
                bomberman.walk((Integer[][]) readObject());
                break;
            case 2:
                bomberman.addUser((User) readObject());
                break;
            case 3:
                bomberman.setMe(byteToInt(b[1], b[2]));
                break;
            case 4:
                bomberman.remove(byteToInt(b[1], b[2]));
                break;
            case 5:
                bomberserver.sendAll(id, 6, b);
                break;
            case 6:
                if (b[1] != id) {
                    bomberman.startWalk(b[1],
                            byteToInt(b[2], b[3]),
                            byteToInt(b[4], b[5]),
                            byteToInt(b[6], b[7]));
                }
                break;
            case 7:
                bomberserver.sendAll(id, 8, b);
                break;
            case 8:
                if (b[1] != id) {
                    bomberman.stopWalk(b[1],
                            byteToInt(b[2], b[3]),
                            byteToInt(b[4], b[5]));
                }
                break;
            case 9:
                bomberserver.sendAll(id, 10, b);
                break;
            case 10:
                bomberman.placeBomb(b[1],
                        byteToInt(b[2], b[3]),
                        byteToInt(b[4], b[5]));
                break;
            case 11:
                bomberserver.sendAll(12, b);
                break;
            case 12:
                bomberman.addPu(0,
                        byteToInt(b[1], b[2]),
                        byteToInt(b[3], b[4]));
                break;
            case 13:
                bomberserver.sendAll(14, b);
                break;
            case 14:
                bomberman.dead(b[1]);
                break;
        }
    }

    public void send(byte[] b) {
        try {
            socket.getOutputStream().write(b);
        } catch (Exception e) {
        }
    }
}
